Abstract
Include here a description of the whole work, use no more than 400 words, you can use **Bold** and *Italic* highlights, also you can inclue [links](www.iteso.mx). Usually is a good strategy to generate this text at the very end of the process, since you have to include all aspects of the work, from a brief introduction, to problem definitions and methods used, to finally the results found.
El obejtivo de este proyecto es la lectura de señales por medio de un analisis tecnico, generar inversiones de trading utilizando herramientas de capitales con el fin de proponer un sistema de trading modelando las señales a traves de la obtención de comunicado y reacción de movimiento a las señales generadas. Basadose en calculos estadístico, Financieros y Computacionales se realiza la mejor toma de decisiones de trading con base en las señales del analisis tecnico en los instrumentos financieros utilizados. El análisis técnico, dentro del análisis bursátil, es el estudio de la acción del mercado, principalmente a través del uso de gráficas, con el propósito de anticipar, con mayor probabilidad cambios en la estructura del mercado. El término “acción del mercado” incluye las tres principales fuentes de información disponibles para el analista técnico. Estas son:
Precio o cotización: La variable más importante de la acción del mercado. Normalmente se representa a través de una gráfica de barras, en la parte superior de la gráfica. Volumen bursátil: La cantidad de unidades o contratos operados durante un cierto período. Se representa como una barra vertical bajo la gráfica de cotizaciones. Interés abierto: Utilizado principalmente en futuros y opciones, representa el número de contratos que permanecen abiertos al cierre del periodo. Se representa como una línea continua por debajo de la acción del precio, pero por encima del volumen. El análisis técnico tuvo sus orígenes en EE. UU. a finales del siglo XIX con Charles Henry Dow creando la Teoría de Dow, adquirió un gran impulso con Ralph Nelson Elliott dentro de los mercados accionarios con su Teoría de las Ondas de Elliott, y posteriormente se extendió al mercado de futuros. Se realizaron los estudios técnicos a traves de bandas de bollinger desarrolladas por John Bollinger (CMT, CFA), las bandas de Bollinger son indicadores populares para el análisis de patrones de precios. El patrón consiste en tres líneas que se superponen con mayor frecuencia (no exclusivamente) al precio de los valores. Las bandas de Bollinger ayudan identificar el rango dentro del cual opera un activo, planteando un marco de referencia para determinar si los precios de un activo están altos o bajos en términos relativos. La línea media del indicador de las bandas de Bollinger es una media móvil (normalmente) del precio (por defecto es una media móvil de 20 períodos). La banda superior de Bollinger se deriva de un cálculo de la desviación estándar del precio añadido al valor medio móvil. Dentro de la lectura de esta herramienta las bandas de Bollinger superior e inferior crean un entorno de tipo de canal para el precio y se espera que envuelvan los movimientos de precio la mayor parte del tiempo. Las bandas de Bollinger superior e inferior proporcionan un rango sugerido para la dispersión de precios y, a su vez, son una medida de la volatilidad de los precios. Para realizar el analisis predictivo en la lectura visual mientras más cerca estén las bandas entre sí (un canal más estrecho), menor será la volatilidad percibida del valor en cuestión en la actualidad, esto representaría un período de consolidación o movimiento no direccional para el mercado que se está evaluando.
Cuanto más ancha sea la separación entre las bandas, mayor será la volatilidad percibida del valor en cuestión actualmente. El hecho de que las bandas estén en proceso de ensanchamiento (lo que se indicaría por las bandas superior e inferior apuntando en sentido contrario) se considera a menudo una indicación de que las primeras etapas de una nueva tendencia de precios direccionales pueden estar comenzando o está en marcha. Esto se toma en cuenta para realizar los movimientos.
Definir el sistema de trading y sus 4 criterios desde un punto de vista financiero.
Basados en el Trading Discrecional-Sistemático se utilizan los 4 criterios precisos como son el Criterio para uso de datos (Tipo de Instrumento e instrumento
Granularidad de precios,Tipo de precios utilizado,Validaciones), Criterio para la generación de señales, Criterio para toma de pérdidas y ganancias. Criterio para dimensionamiento de posiciones.Se realizó el proyecto con un Capital inicial de $100,000 usd invertidos en criptomoneda convertida a dólar tal es el caso de comprar BTC (Bitcoin) con un limite de riesgo máximo por operación (pérdida máximo) de 1,000 usd. Este plan de trabajo se divide los datos de la siguiente manera utilizando las fechas comprendidas entre:
• Periodo de entrenamiento: 01/ene/2019 - 01/ene/2020
• Periodo de prueba: 01/Feb/2020 - 01/Feb/2021
Se utilizó 2 medidas de analisis técnicos como herramientas para la generación de oportunidades de trading, se define el sistema de trading y sus 4 criterios desde un punto de vista financiero. Se utiliza el apoyo en aspectos computacionales y el apoyo en aspectos estadísticos. La configuración de parámetros que se eligió del periodo de entrenamiento, como los resultados en el periodo de prueba con los parámetros de la configuración elegida del periodo de entrenamiento (con los mismos datos pero en periodos diferentes). Se realizar una propuesta de algoritmo a detalle con uso de datos, para el criterio 2: Generación de señal de compra o de venta.
Para el desarrollo de este Laboratorio, se hizo uso de múltiples librerias, contenidas en el archivo requirements.txt, a continuación se anotará cada una de ellas y una breve descripción de para que sirve y en que se uso en el laboratorio. • jupyter: Libreria que nos permite usar jupyter notebook, se menciona en nuestros requerimientos con el objetivo de poder correr el programa desde terminal, una vez activo el ambiente virtual para continuar con el desarrollo de nuestro modulo. • numpy: Una de las librerías más importantes de Python, es comúnmente usada para definir objetos y operaciones matemáticas. Es usado en este proyecto para esto mismo (ejemplo crear arrays, realizar operaciones matriciales, etc.). • pandas Librería usada para la creación y operacion de data frames. • pandas-datareader: Sub-librería de pandas que sirve para poder leer datos en la web de diferentes fuentes de información, es usada en este laboratorio para bajar información de manera rápida de la API de yahoo-finance. • datetime: Usada para generar time-stamps, con el objetivo de acceder a las propiedades y ventajas de esta misma, de forma rápida. • plotly: Librería que nos permite hacer representaciones gráficas. • MetaTrader5: Librería de FXPRO que sirve como "API" para importar información del programa.
Las bandas de Bollinger superior e inferior crean un entorno de tipo de canal para el precio y se espera que envuelvan los movimientos de precio la mayor parte del tiempo. Las bandas de Bollinger superior e inferior proporcionan un rango sugerido para la dispersión de precios y, a su vez, son una medida de la volatilidad de los precios.
Cuanto más cerca estén las bandas entre sí (un canal más estrecho), menor será la volatilidad percibida del valor en cuestión en la actualidad. Para los chartistas, esto representaría un período de consolidación o movimiento no direccional para el mercado que se está evaluando.
Cuanto más ancha sea la separación entre las bandas, mayor será la volatilidad percibida del valor en cuestión actualmente. El hecho de que las bandas estén en proceso de ensanchamiento (lo que se indicaría por las bandas superior e inferior apuntando en sentido contrario) se considera a menudo una indicación de que las primeras etapas de una nueva tendencia de precios direccionales pueden estar comenzando o está en marcha.
In order to run this notebook, it is necessary to have installed and/or have the requirements.txt file with the following:
The following are the file dependencies that are needed to run this notebook:
import functions as fun
import data as dt
import visualizations as vs
2022-12-02 12:19:14,439 - numexpr.utils - INFO - NumExpr defaulting to 4 threads.
2022-12-02 12:23:05,526 - pyswarms.single.global_best - INFO - Optimize for 1000 iters with {'c1': 1, 'c2': 1, 'w': 0.9}
pyswarms.single.global_best: 100%|██████████|1000/1000, best_cost=1e+7
2022-12-02 12:23:12,677 - pyswarms.single.global_best - INFO - Optimization finished | best cost: 10000000.0, best pos: [7.75788862e-01 6.98861549e+04]
Datos precios durante el periodo de entrenamiento (2019-2020)
dt.data_E
| Unnamed: 0 | time | open | high | low | close | tick_volume | spread | real_volume | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 1546387200 | 3776.40 | 3875.24 | 3746.32 | 3860.78 | 2241708 | 0 | 5130062 |
| 1 | 1 | 1546473600 | 3860.78 | 3891.23 | 3735.28 | 3770.96 | 7253573 | 0 | 6835392 |
| 2 | 2 | 1546560000 | 3770.96 | 3826.24 | 3706.38 | 3810.35 | 30337620 | 0 | 6835366 |
| 3 | 3 | 1546819200 | 4008.20 | 4046.24 | 3945.24 | 3981.47 | 3247554 | 0 | 6871753 |
| 4 | 4 | 1546905600 | 3981.47 | 4087.36 | 3926.25 | 3976.13 | 1649465 | 0 | 6835387 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 254 | 254 | 1577145600 | 7294.75 | 7412.25 | 7139.25 | 7180.25 | 340064 | 0 | 3765000 |
| 255 | 255 | 1577318400 | 7162.75 | 7419.25 | 7150.25 | 7173.75 | 278882 | 0 | 3240000 |
| 256 | 256 | 1577404800 | 7172.75 | 7240.75 | 7026.75 | 7204.50 | 322672 | 0 | 4308954 |
| 257 | 257 | 1577664000 | 7373.00 | 7412.00 | 7181.50 | 7231.75 | 279110 | 0 | 4308833 |
| 258 | 258 | 1577750400 | 7202.75 | 7289.00 | 7097.50 | 7128.75 | 190402 | 0 | 3765253 |
259 rows × 9 columns
Datos precios durante el periodo de prueba (2020-2021)
dt.data_P
| Unnamed: 0 | time | open | high | low | close | tick_volume | spread | real_volume | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 1580688000 | 9347.25 | 9592.44 | 9200.25 | 9261.25 | 526838 | 0 | 4299151 |
| 1 | 1 | 1580774400 | 9276.75 | 9330.25 | 9059.45 | 9117.25 | 551460 | 0 | 4302000 |
| 2 | 2 | 1580860800 | 9107.31 | 9758.49 | 9104.75 | 9668.24 | 960508 | 0 | 4305000 |
| 3 | 3 | 1580947200 | 9572.74 | 9846.24 | 9507.99 | 9722.24 | 1584884 | 0 | 4306301 |
| 4 | 4 | 1581033600 | 9730.49 | 9865.99 | 9628.24 | 9729.74 | 2359234 | 0 | 4305000 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 254 | 254 | 1611619200 | 32616.75 | 32758.50 | 30772.45 | 31941.56 | 2145188 | 0 | 21600000 |
| 255 | 255 | 1611705600 | 31941.56 | 32853.22 | 29167.31 | 30928.50 | 2129974 | 0 | 21600000 |
| 256 | 256 | 1611792000 | 30928.50 | 33258.13 | 29823.02 | 33174.73 | 2121008 | 0 | 21600000 |
| 257 | 257 | 1611878400 | 33174.73 | 38544.95 | 31912.50 | 34615.85 | 2127008 | 0 | 21568500 |
| 258 | 258 | 1612137600 | 32541.50 | 34630.11 | 32261.87 | 33590.62 | 2130718 | 0 | 21600000 |
259 rows × 9 columns
Durante este proyecto se utilizan las siguientes herramientas de análisis técnico para generar señales de compra y de venta.
Se utilizo bandas de bollinger Desarrolladas por John Bollinger (CMT, CFA), las bandas de Bollinger son indicadores populares para el análisis de patrones de precios. El patrón consiste en tres líneas que se superponen con mayor frecuencia (no exclusivamente) al precio de los valores. Las bandas de Bollinger ayudan identificar el rango dentro del cual opera un activo, planteando un marco de referencia para determinar si los precios de un activo están altos o bajos en términos relativos. La línea media del indicador de las bandas de Bollinger es una media móvil (normalmente) del precio (por defecto es una media móvil de 20 períodos). La banda superior de Bollinger se deriva de un cálculo de la desviación estándar del precio añadido al valor medio móvil. La banda inferior de Bollinger se deriva de un cálculo de la desviación estándar del precio restado del valor medio móvil.
dt.data_ES
| Unnamed: 0 | time | open | high | low | close | tick_volume | spread | real_volume | bb_bbm | bb_bbh | bb_bbl | bb_high_signal | bb_low_signal | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 20 | 20 | 1548806400 | 3377.49 | 3435.44 | 3349.37 | 3408.75 | 4048838 | 0 | 6840090 | 3637.959048 | 4004.133975 | 3271.784120 | 0.0 | 0.0 |
| 21 | 21 | 1548892800 | 3408.75 | 3448.57 | 3372.38 | 3393.54 | 853227 | 0 | 6840127 | 3615.709524 | 3981.805279 | 3249.613769 | 0.0 | 0.0 |
| 22 | 22 | 1548979200 | 3393.54 | 3432.37 | 3350.26 | 3425.32 | 1652827 | 0 | 6835363 | 3599.250476 | 3967.022038 | 3231.478914 | 0.0 | 0.0 |
| 23 | 23 | 1549238400 | 3371.25 | 3411.60 | 3369.05 | 3393.46 | 2448519 | 0 | 6840262 | 3579.398571 | 3944.443706 | 3214.353436 | 0.0 | 0.0 |
| 24 | 24 | 1549324800 | 3393.46 | 3406.23 | 3375.81 | 3399.04 | 3250885 | 0 | 6840255 | 3551.663810 | 3876.601449 | 3226.726170 | 0.0 | 0.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 254 | 254 | 1577145600 | 7294.75 | 7412.25 | 7139.25 | 7180.25 | 340064 | 0 | 3765000 | 7235.271429 | 7688.730962 | 6781.811895 | 0.0 | 0.0 |
| 255 | 255 | 1577318400 | 7162.75 | 7419.25 | 7150.25 | 7173.75 | 278882 | 0 | 3240000 | 7239.290476 | 7688.985981 | 6789.594971 | 0.0 | 0.0 |
| 256 | 256 | 1577404800 | 7172.75 | 7240.75 | 7026.75 | 7204.50 | 322672 | 0 | 4308954 | 7224.019048 | 7655.242185 | 6792.795910 | 0.0 | 0.0 |
| 257 | 257 | 1577664000 | 7373.00 | 7412.00 | 7181.50 | 7231.75 | 279110 | 0 | 4308833 | 7209.305714 | 7616.728073 | 6801.883356 | 0.0 | 0.0 |
| 258 | 258 | 1577750400 | 7202.75 | 7289.00 | 7097.50 | 7128.75 | 190402 | 0 | 3765253 | 7182.850476 | 7531.350887 | 6834.350066 | 0.0 | 0.0 |
239 rows × 14 columns
El Oscilador Estocástico (Stochastic Oscillator en inglés) es una variable estadística que está construida a través de la posición de una Cotización con respecto a su máximo y a su mínimo, dentro de un período específico.
Esta variable se mueve dentro del intervalo cerrado es decir, entre cero y 100 por ciento.
A través de su examen gráfico, este instrumento de Análisis técnico bursátil, entrega señales de compra o venta.
Este Estadístico se puede expresar formalmente de la siguiente forma:
$$ S = 100(\frac{VC-Min}{Max-Min}) $$S: Es el estocástico.
VC: Es el Valor de Cierre de la última sesión.
Máx y Mín: Es el valor máximo y mínimo, respectivamente, de la cotización dentro del período que estamos analizando.
Señales:
Las señales, que indiquen al analista que la Acción estudiada se debe comprar o vender, se perciben principalmente cuando la línea del oscilador estocástico (S) corta a su media móvil.
Entonces, decimos que si S corta en forma ascendente a se nos da señal de compra. Y si S se mantiene por sobre su media móvil, la señal se mantiene. En el gráfico se puede observar esta situación en la circunferencia de color azul.
Inversamente, si S corta a en forma descendente se da señal de venta, y mientras S se mantenga abajo, la tendencia se mantendrá en venta. Este caso observa en el gráfico en la circunferencia de color amarillo.
dt.data_ES2
| Unnamed: 0 | time | open | high | low | close | tick_volume | spread | real_volume | stochastic | stochastic_buy_signal | stochastic_sell_signal | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 13 | 13 | 1548028800 | 3515.45 | 3544.94 | 3482.49 | 3497.50 | 2451643 | 0 | 6840151 | 4.344442 | True | False |
| 14 | 14 | 1548115200 | 3497.50 | 3587.53 | 3402.36 | 3549.88 | 10772862 | 0 | 6835359 | 21.535766 | False | False |
| 15 | 15 | 1548201600 | 3549.88 | 3589.22 | 3498.51 | 3521.29 | 1651960 | 0 | 6840203 | 17.362044 | True | False |
| 16 | 16 | 1548288000 | 3521.29 | 3572.07 | 3504.88 | 3547.24 | 4052829 | 0 | 6840137 | 21.150365 | False | False |
| 17 | 17 | 1548374400 | 3547.24 | 3554.75 | 3490.64 | 3534.75 | 2454167 | 0 | 6835422 | 19.327007 | True | False |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 254 | 254 | 1577145600 | 7294.75 | 7412.25 | 7139.25 | 7180.25 | 340064 | 0 | 3765000 | 61.539946 | False | False |
| 255 | 255 | 1577318400 | 7162.75 | 7419.25 | 7150.25 | 7173.75 | 278882 | 0 | 3240000 | 61.038209 | False | False |
| 256 | 256 | 1577404800 | 7172.75 | 7240.75 | 7026.75 | 7204.50 | 322672 | 0 | 4308954 | 63.411810 | False | False |
| 257 | 257 | 1577664000 | 7373.00 | 7412.00 | 7181.50 | 7231.75 | 279110 | 0 | 4308833 | 65.515245 | False | False |
| 258 | 258 | 1577750400 | 7202.75 | 7289.00 | 7097.50 | 7128.75 | 190402 | 0 | 3765253 | 57.564647 | False | False |
246 rows × 12 columns
Usamos un volumen de .5 BTCUSD con 9,000 pips y al final de cada cierre de operacion obtenemos los siguientes retornos.
dt.transacciones
[-1.4703027877055015, 2.10397821384152, 0.39400277409900586, 0.6795801800433627, 24.74927206585117, -0.5697166764050448, 2.946211955352939, 4.203954588457898, 0.6096923118458611, 3.3736425872424114, 4.989495870494304, 8.504071697533842, 61.80028338556395, -4.493974367149136, 14.320135095638609, -1.618684618198521, -2.7058068491040688, 4.3485230284638865, 19.436288107484362, -1.4344323360321325, -4.555576687351342, 7.270972323175853, -3.975517978309057, 5.92351810771344, 9.714489374905625, 22.721584445968286, 11.663534681397902, 29.797978302313354, -4.349247116631223, 2.4672604278214307, 0.7710811719376253, -4.490008193251067, 11.478195830988767, 1.3770229177863043, -3.037253106030908, -3.6091799307492023, 2.520134754407885, 13.948782538308407, -1.5562600625154133, -29.976883442989326, -6.969144440352802, 2.2083778431552386, -0.9125131174323661, -0.5527551626248527, -4.708483125643773, 17.791965920245758, 26.023448285544504, -1.6501089813650454, -5.648630572842366, -6.858569525330316, -3.3020275267200487, -7.828474697033597, -1.3672093617821506]
Y obtenemos el siguiente retorno promedio.
fun.Average(dt.transacciones)
3.9716361910195137
Se muestra el capital resultante de los ultimos días de operacion.
dt.a.tail()
| days | capital | |
|---|---|---|
| 48 | 226 | 119726.92 |
| 49 | 227 | 118786.88 |
| 50 | 228 | 118346.92 |
| 51 | 229 | 116288.80 |
| 52 | 231 | 113428.00 |
vs.capital(dt.a)
Nuestra rentabilidad en la primera prueba fue de:
dt.retorno_prueba
113428.00000000003
Se realizó una busqueda exahustiva para encontrar los mejores parametros de volumen, pips de stop loss y pips de take profit que maximizan el radio de Sharpe, en donde se realizó sobre el arange:
vol=np.arange(.5,8,.5)
pips=np.arange(1000,100000,5000).
dt.busqueda
| Volume | Stop Loss | Take profit | Sharpe | |
|---|---|---|---|---|
| 0 | 0.5 | 1000 | 1000 | 0.059903 |
| 1 | 0.5 | 1000 | 6000 | 0.065393 |
| 2 | 0.5 | 1000 | 11000 | 0.070139 |
| 3 | 0.5 | 1000 | 16000 | 0.073836 |
| 4 | 0.5 | 1000 | 21000 | 0.076620 |
| ... | ... | ... | ... | ... |
| 5995 | 7.5 | 96000 | 76000 | 0.106958 |
| 5996 | 7.5 | 96000 | 81000 | 0.106958 |
| 5997 | 7.5 | 96000 | 86000 | 0.106958 |
| 5998 | 7.5 | 96000 | 91000 | 0.106958 |
| 5999 | 7.5 | 96000 | 96000 | 0.110016 |
6000 rows × 4 columns
Los parametros que maximizan el Sharpe son los siguientes:
dt.best_param
| Volume | Stop Loss | Take profit | Sharpe | |
|---|---|---|---|---|
| 5963 | 7.5 | 91000 | 16000 | 0.195755 |
| 5983 | 7.5 | 96000 | 16000 | 0.195755 |
Se aplican estos al periodo de prueba y obtenemos los suiguientes retornos:
dt.transacciones_a2
[-14.312269260826207, -3.2404077253218895, -21.316275945885444, 3.4994571426392405, 3.5051194810335478, 4.177367778600443, -2.1205473483900112, -0.3990599809340638, 3.0453416508303723, 2.7343977438555105, -5.826848782959332, -0.5620688909550885, -1.4876275595277784, -7.19582124201974, 1.3711216865984455, 3.930621255124566, 2.2081677112936537, 21.722512337127394, 2.957370165615278, 7.4884669142532045, 4.437919348834675, -2.2165586168620175, 2.4873769415169678, -4.2316901779869545, 2.5380048263710795, 18.33097524097527, 6.821133667471966, 10.729431351502958, 9.070825775368307, 21.989408670125414, 15.664716638148489, 25.892723336975912, -1.2001037886645016]
Con un promedio de:
fun.Average(dt.transacciones_a2)
3.3482781922402927
Al final de los días de operación en el periódo de prueba (2020-2021) se obtuvo el siguiente capital:
dt.a2.tail()
| days | capital | |
|---|---|---|
| 28 | 236 | 262657.750 |
| 29 | 238 | 283416.925 |
| 30 | 239 | 299527.150 |
| 31 | 240 | 327851.950 |
| 32 | 241 | 320596.900 |
vs.capital(dt.a2)
También se realizó una optimización con el PSO que dio el siguiente resultado con los siguientes parámetros.
print("Best position: ", dt.best_pos)
Best position: [7.800000e-01 6.988615e+04]
A lo largo de este laboratorio nos enfrentamos a distintos desafíos, comenzando con una gran incertidumbre de como realizar nuestro analisis. Por fortuna encontramos en las librerías recomendadas por el profesor ta (Techical Analysis) que nos funcionò para aplicar nuestros modelos de analisis têcnico sobre Bandas de Bollinger y RSI.
Fue un arduo trabajo el que realizamos para poder codificar los rendimientos esperados ya que creamos varios intentos basados en un planteamiento que por fortuna logramos corregir, así generando el capital proyectado y el rendimiento esperado. Usamos una muestra de prueba para despues entrenar el modelo con una busqueda exahustiva.
Una vez obtenidos los resultados realizamos una segunda proyecciòn ya con el stop loss, take profit y volumen que obtuvimos en la busqueda exahustiva. Finalmente obtuvimos un capital de 320k lo cual nos dio un buen escenario. Consecuentemente empezamos a programar el PSO pudimos encintrar la mejor posiciòn. Ahora podemos comprender la importancia de las bases en la programación en los sistemas de trading, con los cuales podemos aceptar o rechazar el activo a tradear, la programación de las señales de compra y venta fueron clave para la realización satisfactoria de este proyecto. Incluso con el analisis tecnico el cual no siemore es excato, logramos obtener un resultado positivo, debido en parte al activo empleado y a la optimizacion de los parametros.
Welcome to Technical Analysis Library in Python’s documentation! — Technical Analysis Library in Python 0.1.4 documentation. (n.d.). https://technical-analysis-library-in-python.readthedocs.io/en/latest/
Rodrigo, J. A. (n.d.). Optimización con enjambre de partículas (Particle Swarm Optimization) python. https://www.cienciadedatos.net/documentos/py02_optimizacion_pso